using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;
using System.Data.SqlClient;
using System.Web;

namespace BusinessUnit
{
    public class Access
    {
        enum AccessType
        {
            Self,
            Unit,
            UnitAndSubUnit
        };
        string str_ConnectionString = "";
        string str_ReturnOwnerIds = "";
        string str_UserId = "";
        string str_OwnerIds = "";
        string str_BuUnitIds = "";
        string str_ReportingTo = "";
        string strpageID = "";

        ArrayList arl_OwnerIds = new ArrayList();
        ArrayList arl_ReportingTo = new ArrayList();
        ArrayList arl_BusinessUnits = new ArrayList();
        ArrayList arl_OverRideOwnerIds = new ArrayList();

        DataTable dt_ReportingTo = new DataTable();
        DataTable dt_BuUnits = new DataTable();
        DataTable dt_Users = new DataTable();

        public string ReportingTo { get { return this.str_ReportingTo; } }

        public string DBConnectionString { get { return this.str_ConnectionString; } set { this.str_ConnectionString = value; } }
        public string UserId { get { return this.str_UserId; } set { this.str_UserId = value; } }

        public DataTable BusinessUnitsTable { get { return this.dt_BuUnits; } }
        public string AllBusinessUnitIdsForSql { get { return this.str_BuUnitIds; } }
        public ArrayList AllBusinessUnitIds { get { return this.arl_BusinessUnits; } }

        public string AllReportingToOwnerIdsForSql { get { return this.str_ReportingTo; } }
        public ArrayList AllReportingToOwnerIds { get { return this.arl_ReportingTo; } }

        public string AllOwnerIdsForSql { get { return this.str_OwnerIds; } }
        public ArrayList AllOwnerIds { get { return this.arl_OwnerIds; } }

        public ArrayList AllOverRideOwnerIds { get { return this.arl_OverRideOwnerIds; } }

        public string AccessableOwners { get { this.ProcessSqlBasedOwnerIds(); return this.str_ReturnOwnerIds; } }

        public string AccessableBuUnits { get { this.ProcessSqlBasedBusinessUnits(); return this.str_BuUnitIds; } }

        public Access(string str_User, string str_ConStr, string str_PageId)
        {
            this.str_ConnectionString = str_ConStr;
            this.UserId = str_User;
            this.dt_BuUnits = this.GetBuisnessUnitTable();
            strpageID = str_PageId;
            if (this.UserId == "")
            {
                return;
            }
            this.dt_Users = this.GetUsersTable();
            DataRow[] drarr_User = dt_Users.Select("user_id='" + this.UserId + "'");
            if (drarr_User.Length == 0)
            {
                return;
            }
            /* // commented by 'Imran Gani' on 05-June-2013 for Org Security (sy_usr_obj)
            DataRow[] drarr_ObjectOverride = this.GetPageDetails(str_PageId).Select("");
            if (drarr_ObjectOverride.Length > 0)
            {
                if (Convert.ToString(drarr_ObjectOverride[0]["access_level"]).ToLower() == "mr"
                    && !this.arl_OverRideOwnerIds.Contains(drarr_User[0]["af_row_id"].ToString())) // mr= My Record
                    this.arl_OverRideOwnerIds.Add(drarr_User[0]["af_row_id"].ToString());

                else if (Convert.ToString(drarr_ObjectOverride[0]["access_level"]).ToLower() == "so"
                    && !this.arl_OverRideOwnerIds.Contains(drarr_User[0]["specific_owner"].ToString())) // so= Specific Owners not implemented
                    this.arl_OverRideOwnerIds.Add(drarr_User[0]["specific_owner"].ToString());

                else if (Convert.ToString(drarr_ObjectOverride[0]["access_level"]).ToLower() == "ar") // ar=All Records
                {
                    foreach (DataRow dr_Owners in dt_Users.Rows)
                    {
                        if (!this.arl_OverRideOwnerIds.Contains(dr_Owners["af_row_id"].ToString()))
                            this.arl_OverRideOwnerIds.Add(dr_Owners["af_row_id"].ToString());
                    }
                }
            }
            else
            {*/
                if (drarr_User[0]["chk_bu_unit"].ToString() != "" && Convert.ToBoolean(drarr_User[0]["chk_bu_unit"]))
                {
                    this.ProcessBusinessUnits();
                }
                if (drarr_User[0]["chk_reporting_to"].ToString() != "" && Convert.ToBoolean(drarr_User[0]["chk_reporting_to"]))
                {
                    this.ProcessReportingToOwners();
                }
            //}
        }
        protected void ProcessSqlBasedOwnerIds()
        {
            this.str_ReturnOwnerIds = "";
            if (this.arl_OverRideOwnerIds.Count > 0)
            {
                foreach (string str_OverRideOwner in this.arl_OverRideOwnerIds)
                {
                    this.str_ReturnOwnerIds += "'" + str_OverRideOwner + "',";
                }
                if (this.str_ReturnOwnerIds != "")
                {
                    this.str_ReturnOwnerIds = " and owner_id in(" + this.str_ReturnOwnerIds.Substring(0, this.str_ReturnOwnerIds.Length - 1) + ")";
                }
            }
            else
            {
                this.str_OwnerIds = "";
                this.str_ReportingTo = "";
                if (this.arl_OwnerIds.Count > 0)
                {
                    foreach (string str_OwnerId in this.arl_OwnerIds)
                    {
                        this.str_OwnerIds += "'" + str_OwnerId + "',";
                    }
                    if (this.str_OwnerIds != "")
                    {
                        this.str_ReturnOwnerIds += " and owner_id in(" + this.str_OwnerIds.Substring(0, this.str_OwnerIds.Length - 1) + ")";
                    }
                }
                if (this.arl_ReportingTo.Count > 0)
                {
                    foreach (string str_ReportingId in this.arl_ReportingTo)
                    {
                        this.str_ReportingTo += "'" + str_ReportingId + "',";
                    }
                    if (this.str_ReportingTo != "")
                    {
                        this.str_ReturnOwnerIds += " and owner_id in(" + this.str_ReportingTo.Substring(0, this.str_ReportingTo.Length - 1) + ")";
                    }
                }
            }
        }
        private void ProcessSqlBasedBusinessUnits()
        {
            this.str_BuUnitIds = "";
            if (this.arl_BusinessUnits.Count > 0)
            {
                foreach (string str_BusinessUnits in this.arl_BusinessUnits)
                {
                    this.str_BuUnitIds += "'" + str_BusinessUnits + "',";
                }
                if (this.str_BuUnitIds != "")
                {
                    //this.str_BuUnitIds = " and af_row_id in(" + this.str_BuUnitIds.Substring(0, this.str_BuUnitIds.Length - 1) + ")";
                    if (strpageID == "p_bu_unit")
                    {
                        HDDatabase HDD = new HDDatabase();
                        DataTable dt_bu = HDD.GetDataTable("Select * from sy_bu_unit");
                        if (dt_bu != null)
                        {
                            if (dt_bu.Rows.Count > 0)
                                for (int i = 0; i < dt_bu.Rows.Count; i++)
                                {
                                    this.str_BuUnitIds += "'" + dt_bu.Rows[i]["af_row_id"].ToString() + "',";
                                }
                        }

                        this.str_BuUnitIds = " and af_row_id in(" + this.str_BuUnitIds.Substring(0, this.str_BuUnitIds.Length - 1) + ")";
                    }
                    else
                        this.str_BuUnitIds = " and bu_id in(" + this.str_BuUnitIds.Substring(0, this.str_BuUnitIds.Length - 1) + ")";
                }
            }
        }
        protected DataTable GetDataTable(SqlCommand sco_BuCmdParam)
        {
            SqlCommand sco_BuCmd = new SqlCommand();
            SqlConnection sqc_BUCon = new SqlConnection();
            SqlDataAdapter sda_BuAdap = null;
            DataTable dt_BuTab = new DataTable();
            if (this.DBConnectionString == "")
            {
                throw new Exception("Connection String not configured.");
            }
            try
            {
                sco_BuCmd = sco_BuCmdParam;
                sqc_BUCon.ConnectionString = this.DBConnectionString;
                sco_BuCmd.Connection = sqc_BUCon;
                sda_BuAdap = new SqlDataAdapter(sco_BuCmd);
                sda_BuAdap.Fill(dt_BuTab);
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                sqc_BUCon.Dispose();
                sco_BuCmd.Dispose();
                sda_BuAdap.Dispose();
            }
            return dt_BuTab;
        }
        protected DataTable GetBuisnessUnitTable()
        {
            DataTable dt_BuUnit = new DataTable();
            SqlCommand sco_BuUnit = new SqlCommand();
            sco_BuUnit.CommandText = " select distinct a.af_row_id as value, isnull(a.bu_id,a.af_row_id) as text,a.bu_desc, a.parent_bu_id as parent_value,a.bu_id,"
                                        + " isnull(b.cnt,0) as count,a.af_row_id ,a.af_row_id as bu_row_id,a.modified_by,a.created_by,a.owner_id from sy_bu_unit a left outer join (select bu_id ,"
                                        + "count(*) cnt from sy_usr group by bu_id) b on a.af_row_id =b.bu_id ";
            dt_BuUnit = this.GetDataTable(sco_BuUnit);
            return dt_BuUnit;
        }
        protected DataTable GetBuisnessUsersUnitTable()
        {
            DataTable dt_UserBuUnit = new DataTable();
            DataColumn dc_UserBuUnit = new DataColumn("value");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("text");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("parent_value");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("access_rights");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("user_id");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("af_row_id");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);
            dc_UserBuUnit = new DataColumn("bu_row_id");
            dt_UserBuUnit.Columns.Add(dc_UserBuUnit);

            DataRow[] drarr_UsersAttachedTo = this.dt_Users.Select("user_id='" + this.UserId + "'");
            DataRow[] drarr_BuUnit = this.dt_BuUnits.Select("bu_row_id='" + Convert.ToString(drarr_UsersAttachedTo[0]["bu_id"]) + "'");
            DataRow dr_BuUnit = dt_UserBuUnit.NewRow();
            dr_BuUnit["value"] = drarr_BuUnit[0]["value"];
            dr_BuUnit["text"] = drarr_BuUnit[0]["text"];
            dr_BuUnit["parent_value"] = drarr_BuUnit[0]["parent_value"];
            dr_BuUnit["access_rights"] = drarr_UsersAttachedTo[0]["access_rights"];
            dr_BuUnit["user_id"] = drarr_UsersAttachedTo[0]["user_id"];
            dr_BuUnit["af_row_id"] = drarr_UsersAttachedTo[0]["af_row_id"];
            dr_BuUnit["bu_row_id"] = drarr_BuUnit[0]["bu_row_id"];
            dt_UserBuUnit.Rows.Add(dr_BuUnit);

            DataTable dt_UsersAccessBuUnit = new DataTable();
            SqlCommand sco_BuUnit = new SqlCommand();
            sco_BuUnit.CommandText = "select * from sy_Usr_Bu where user_id='" + Convert.ToString(drarr_UsersAttachedTo[0]["af_row_id"]) + "'";
            dt_UsersAccessBuUnit = this.GetDataTable(sco_BuUnit);
            foreach (DataRow dr_UsersAccessBuUnit in dt_UsersAccessBuUnit.Rows)
            {
                DataRow[] drarr_UsersAccessBuUnit = this.dt_BuUnits.Select("bu_row_id='" + Convert.ToString(dr_UsersAccessBuUnit["bu_id"]) + "'");
                DataRow dr_UsersAccessedBuUnit = dt_UserBuUnit.NewRow();
                dr_UsersAccessedBuUnit["value"] = drarr_UsersAccessBuUnit[0]["value"];
                dr_UsersAccessedBuUnit["text"] = drarr_UsersAccessBuUnit[0]["text"];
                dr_UsersAccessedBuUnit["parent_value"] = drarr_UsersAccessBuUnit[0]["parent_value"];
                dr_UsersAccessedBuUnit["access_rights"] = dr_UsersAccessBuUnit["access_rights"];
                dr_UsersAccessedBuUnit["user_id"] = drarr_UsersAttachedTo[0]["user_id"];
                dr_UsersAccessedBuUnit["af_row_id"] = drarr_UsersAttachedTo[0]["af_row_id"];
                dr_UsersAccessedBuUnit["bu_row_id"] = drarr_UsersAccessBuUnit[0]["bu_row_id"];
                dt_UserBuUnit.Rows.Add(dr_UsersAccessedBuUnit);
            }
            return dt_UserBuUnit;
        }
        protected DataTable GetUsersTable()
        {
            DataTable dt_Users = new DataTable();
            SqlCommand sco_Users = new SqlCommand();
            sco_Users.CommandText = "select * from sy_Usr";
            dt_Users = this.GetDataTable(sco_Users);
            return dt_Users;
        }
        protected DataTable GetPageDetails(string str_PageID)
        {
            DataTable dt_PageDetails = new DataTable();
            SqlCommand sco_PageDetails = new SqlCommand();
            sco_PageDetails.CommandText = "select obj.* from sy_pg page inner join sy_usr_obj obj on "
                                        + "page.object_id=obj.obj_id and user_id=@user_id and page_id=@page_id";
            sco_PageDetails.Parameters.AddWithValue("@page_id", str_PageID);
            sco_PageDetails.Parameters.AddWithValue("@user_id", this.UserId);
            dt_PageDetails = this.GetDataTable(sco_PageDetails);
            return dt_PageDetails;
        }

        protected void ProcessBusinessUnits()
        {
            HttpContext.Current.Session["arl_BusinessUnits"] = "";
            HttpContext.Current.Session["arl_OwnerIds"] = "";
            if (HttpContext.Current != null && HttpContext.Current.Session != null)
            {
                if (HttpContext.Current.Session["arl_BusinessUnits"] != null && HttpContext.Current.Session["arl_OwnerIds"] != null && HttpContext.Current.Session["arl_BusinessUnits"] != "" && HttpContext.Current.Session["arl_OwnerIds"] != "")
                {
                    this.arl_OwnerIds = (ArrayList)HttpContext.Current.Session["arl_OwnerIds"];
                    this.arl_BusinessUnits = (ArrayList)HttpContext.Current.Session["arl_BusinessUnits"];
                }
                else
                {
                    DataTable dt_UsersBusinessUnit = this.GetBuisnessUsersUnitTable();
                    foreach (DataRow dr_BuUnit in dt_UsersBusinessUnit.Select("user_id='" + this.UserId + "'"))
                    {
                        if (Convert.ToString(dr_BuUnit["access_rights"]).ToLower() == "se")
                        {
                            if (!this.arl_OwnerIds.Contains(dr_BuUnit["af_row_id"]))
                                this.arl_OwnerIds.Add(dr_BuUnit["af_row_id"]);
                            if (!this.arl_BusinessUnits.Contains(dr_BuUnit["value"]))
                            {
                                this.arl_BusinessUnits.Add(dr_BuUnit["value"]);
                                this.arl_BusinessUnits.Add(dr_BuUnit["bu_row_id"]);
                            }
                        }
                        else
                        {
                            foreach (DataRow dr_BuOwnerUnit in this.dt_Users.Select("bu_id='" + Convert.ToString(dr_BuUnit["bu_row_id"]) + "'"))
                            {
                                if (!this.arl_OwnerIds.Contains(dr_BuOwnerUnit["af_row_id"]))
                                    this.arl_OwnerIds.Add(dr_BuOwnerUnit["af_row_id"]);
                            }
                            if (!this.arl_BusinessUnits.Contains(dr_BuUnit["value"]))
                            {
                                this.arl_BusinessUnits.Add(dr_BuUnit["value"]);
                                this.arl_BusinessUnits.Add(dr_BuUnit["bu_row_id"]);
                            }
                            if (Convert.ToString(dr_BuUnit["access_rights"]).ToLower() == "su")
                            {
                                this.ProcessChildBusinessUnits(Convert.ToString(dr_BuUnit["value"]));
                            }
                        }
                    }
                    HttpContext.Current.Session["arl_BusinessUnits"] = this.arl_BusinessUnits;
                    HttpContext.Current.Session["arl_OwnerIds"] = this.arl_OwnerIds;
                }
            }
        }
        private void ProcessChildBusinessUnits(string str_BUId)
        {
            foreach (DataRow dr_ChildBU in this.dt_BuUnits.Select("parent_value='" + str_BUId + "'"))
            {
                foreach (DataRow dr_BuOwnerUnit in this.dt_Users.Select("bu_id='" + Convert.ToString(dr_ChildBU["bu_row_id"]) + "'"))
                {
                    if (!this.arl_OwnerIds.Contains(dr_BuOwnerUnit["af_row_id"]))
                        this.arl_OwnerIds.Add(dr_BuOwnerUnit["af_row_id"]);
                }
                if (!this.arl_BusinessUnits.Contains(dr_ChildBU["value"]))
                {
                    this.arl_BusinessUnits.Add(dr_ChildBU["value"]);
                    this.arl_BusinessUnits.Add(dr_ChildBU["bu_row_id"]);
                }
                DataRow[] dr_GrantChildBU = this.dt_BuUnits.Select("parent_value='" + Convert.ToString(dr_ChildBU["value"]) + "'", "value");
                if (dr_GrantChildBU.Length > 0 && str_BUId != dr_ChildBU["value"].ToString())
                {
                    this.ProcessChildBusinessUnits(Convert.ToString(dr_ChildBU["value"]));
                }
            }
        }
        protected void ProcessReportingToOwners()
        {
            DataRow[] drarr_ChildUsers = this.dt_Users.Select("user_id='" + str_UserId + "'");
            if (drarr_ChildUsers.Length > 1)
            {
                if (!this.arl_ReportingTo.Contains(drarr_ChildUsers[0]["reporting_to"]))
                    this.arl_ReportingTo.Add(drarr_ChildUsers[0]["reporting_to"]);
                this.ProcessChildReportingToOwners(Convert.ToString(drarr_ChildUsers[0]["reporting_to"]));
            }
        }
        private void ProcessChildReportingToOwners(string str_UserId)
        {
            foreach (DataRow dr_ChildUsers in this.dt_Users.Select("reporting_to='" + str_UserId + "'"))
            {
                if (!this.arl_ReportingTo.Contains(dr_ChildUsers["user_id"]))
                    this.arl_ReportingTo.Add(dr_ChildUsers["user_id"]);
                DataRow[] dr_GrantChildUsers = this.dt_Users.Select("reporting_to='" + Convert.ToString(dr_ChildUsers["user_id"]) + "'", "user_id");
                if (dr_GrantChildUsers.Length > 0)
                {
                    this.ProcessChildReportingToOwners(Convert.ToString(dr_ChildUsers["user_id"]));
                }
            }
        }
        public DataSet ApplyBUSecurity(DataSet ds_UserData)
        {
            DataTable dt_UserData = ds_UserData.Tables[0].Clone();
            foreach (DataRow dr_UserData in ds_UserData.Tables[0].Select("owner_id in (" + this.AccessableOwners + ")"))
            {
                dt_UserData.Rows.Add(dr_UserData);
            }
            ds_UserData.Tables.Remove(ds_UserData.Tables[0]);
            ds_UserData.Tables.Add(dt_UserData);
            return ds_UserData;
        }
    }
}
